package com.lmbx.shzh.service.impl;

import com.lmbx.shzh.constant.AppConstants;
import com.lmbx.shzh.domain.common.ResponseResult;
import com.lmbx.shzh.domain.dto.WeatherDTO;
import com.lmbx.shzh.domain.vo.WeatherVO;
import com.lmbx.shzh.exception.BusinessException;
import com.lmbx.shzh.exception.ErrorCodeEnum;
import com.lmbx.shzh.service.WeatherService;
import com.lmbx.shzh.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Auther: wyl
 * @Date: 2021/5/12
 * @Description:
 */
@Slf4j
@Service
public class WeatherServiceImpl implements WeatherService {

    @Value("${weatherUrl}")
    private String weatherUrl;
    @Value("${wthCloud}")
    private String wthCloud;
    @Autowired
    private RestTemplate restTemplate;


    /**
     * 获得华北地区雷达图
     *
     * @return
     */
    @Cacheable(value = AppConstants.WEATHER_API, key = "#num")
    @Override
    public ResponseResult getWeather(int num) {
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime localDateTime12 = localDateTime.minusHours(12);
        long etm = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long stm = localDateTime12.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        // 获得最近12小时内的雷达图
        String url = weatherUrl + "&stm=" + stm + "&etm=" + etm;
        ResponseEntity<String> resultEntity = restTemplate.getForEntity(url, String.class);
        String body = resultEntity.getBody();
        List<WeatherDTO> list = parseResult(body);
        if (list == null) {
            throw new BusinessException(ErrorCodeEnum.WEATHER_FAILURE);
        }
        // 返回前台需要的格式，应该在controller层编写，传输层使用dto，略
/*        List<WeatherVO> resList = list.stream().map(obj -> {
            WeatherVO weatherVO = new WeatherVO();
            weatherVO.setDateTime(obj.getTM());
            weatherVO.setUrl(obj.getWEBPATH());
            return weatherVO;
        }).collect(Collectors.toList());
        resList.subList(0,num); // 反序列化会有问题
        */

        List<WeatherVO> resList = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            WeatherDTO dto = list.get(i);
            WeatherVO weatherVO = new WeatherVO();
            weatherVO.setDateTime(dto.getTM());
            weatherVO.setUrl(dto.getWEBPATH());
            resList.add(weatherVO);
        }

        return ResponseResult.success(resList);
    }

    /**
     * 获得时间段内华北地区雷达图信息
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    @Cacheable(value = AppConstants.WEATHER_API, key = "#startTime+'-'+#endTime")
    @Override
    public ResponseResult getWeatherList(long startTime, long endTime) {
        String url = weatherUrl + "&stm=" + startTime + "&etm=" + endTime;
        ResponseEntity<String> resultEntity = restTemplate.getForEntity(url, String.class);
        String body = resultEntity.getBody();
        List<WeatherDTO> list = parseResult(body);
        if (list == null) {
            throw new BusinessException(ErrorCodeEnum.WEATHER_FAILURE);
        }
        // 返回前台需要的格式，应该在controller层编写，传输层使用dto，略
        List<WeatherVO> resList = list.stream().map(obj -> {
            WeatherVO weatherVO = new WeatherVO();
            weatherVO.setDateTime(obj.getTM());
            weatherVO.setUrl(obj.getWEBPATH());
            return weatherVO;
        }).collect(Collectors.toList());

        return ResponseResult.success(resList);
    }

    @Override
    public ResponseResult getWthCloud(int num) {
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime localDateTime12 = localDateTime.minusHours(12);
        long etm = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long stm = localDateTime12.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        // 获得最近12小时内的雷达图
        String url = wthCloud + "&stm=" + stm + "&etm=" + etm;
        ResponseEntity<String> resultEntity = restTemplate.getForEntity(url, String.class);
        String body = resultEntity.getBody();
        List<WeatherDTO> list = parseResult(body);
        if (list == null) {
            throw new BusinessException(ErrorCodeEnum.WEATHER_FAILURE);
        }
        List<WeatherVO> resList = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            WeatherDTO dto = list.get(i);
            WeatherVO weatherVO = new WeatherVO();
            weatherVO.setDateTime(dto.getTM());
            weatherVO.setUrl(dto.getWEBPATH());
            resList.add(weatherVO);
        }
        return ResponseResult.success(resList);
    }

    @Override
    public ResponseResult getWthCloudList(long startTime, long endTime) {
        String url = wthCloud + "&stm=" + startTime + "&etm=" + endTime;
        ResponseEntity<String> resultEntity = restTemplate.getForEntity(url, String.class);
        String body = resultEntity.getBody();
        List<WeatherDTO> list = parseResult(body);
        if (list == null) {
            throw new BusinessException(ErrorCodeEnum.WEATHER_FAILURE);
        }
         List<WeatherVO> resList = list.stream().map(obj -> {
            WeatherVO weatherVO = new WeatherVO();
            weatherVO.setDateTime(obj.getTM());
            weatherVO.setUrl(obj.getWEBPATH());
            return weatherVO;
        }).collect(Collectors.toList());

        return ResponseResult.success(resList);
    }


    /**
     * 获得第一个雷达图信息
     *
     * @param xml
     * @return
     */
    private List<WeatherDTO> parseResult(String xml) {
        try (InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));) {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = factory.newDocumentBuilder();
            Document document = docBuilder.parse(is);
            Element element = document.getDocumentElement();

            String text = element.getTextContent();

            // 转java对象
            List<WeatherDTO> weatherDTOList = JsonUtils.toObjList(text, WeatherDTO.class);

            if (weatherDTOList == null || weatherDTOList.size() < 1) {
                log.error("获得雷达图失败");
                return null;
            }
            return weatherDTOList;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获得雷达图失败,err={}", e.getMessage());
        }
        return null;
    }
}
